package com.starbaba.util;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author Yukinomiu
 * @version 1.0
 */
public final class QueryListUtil {

    private QueryListUtil() {
    }

    public static DataTableResponseInfo getDataTableResponseInfo() {
        return new DataTableResponseInfo();
    }

    @SuppressWarnings("unchecked")
    public static DataTableResponseInfo getDataTableResponseInfo(Integer echo, Integer totalCount, List data) {
        if (echo == null) {
            echo = 0;
        }
        if (data == null) {
            data = new ArrayList(0);
        }
        return new DataTableResponseInfo(echo + 1, totalCount, totalCount, data);
    }

    public static Map<String, Object> getRequestParamsMap(HttpServletRequest request) {
        if (request == null) throw new IllegalArgumentException("request can not be null");
        Map<String, Object> result = new HashMap<>();


        Map<String, String[]> paramsMap = request.getParameterMap();
        for (String k : paramsMap.keySet()) {
            String[] v = paramsMap.get(k);
            if (v.length != 1) {
                for (int i = 0; i < v.length; i++) {
                    v[i] = v[i].trim();
                }
                result.put(k, v);
            }
            else {
                result.put(k, v[0].trim());
            }
        }
        return result;
    }

    public static void dropEmptyParams(Map<String, Object> paramsMap) {
        if (paramsMap == null) throw new IllegalArgumentException("paramsMap can not be null");
        Iterator<Map.Entry<String, Object>> it = paramsMap.entrySet().iterator();

        while (it.hasNext()) {
            Map.Entry<String, Object> e = it.next();
            Object v = e.getValue();
            if (v instanceof String && StringUtils.isEmpty((String) v)) {
                it.remove();
            }
        }
    }

    public static DataTableRequestInfo getDataTableRequestInfo(Map<String, Object> paramsMap) throws Exception {
        if (paramsMap == null) throw new IllegalArgumentException("paramsMap can not be null");
        Object dataTableConfig = null;
        if (!paramsMap.containsKey("aoData") || !((dataTableConfig = paramsMap.get("aoData")) instanceof String))
            throw new IllegalArgumentException("paramsMap haven't aoData Json String");

        String dataTableJson = (String) dataTableConfig;
        Map<String, String> dataTableParams = new HashMap<>();
        JSONArray jsonarray = JSONArray.fromObject(dataTableJson);
        for (int i = 0; i < jsonarray.size(); i++) {
            JSONObject obj = (JSONObject) jsonarray.get(i);
            dataTableParams.put(obj.get("name").toString(), obj.get("value").toString());
        }

        Integer echo = Integer.valueOf(dataTableParams.get("sEcho"));
        Integer start = Integer.valueOf(dataTableParams.get("iDisplayStart"));
        Integer limit = Integer.valueOf(dataTableParams.get("iDisplayLength"));
        String[] searchColumns = dataTableParams.get("sColumns").split(",");
        Integer sortColIndex = Integer.valueOf(dataTableParams.get("iSortCol_0"));
        String orderLaw = dataTableParams.get("sSortDir_0");
        String needToOrderCol = sortColIndex < searchColumns.length ? searchColumns[sortColIndex] : null;
        return new DataTableRequestInfo(echo, start, limit, searchColumns, needToOrderCol, orderLaw);
    }

    public static class DataTableResponseInfo implements Serializable {

        private static final long serialVersionUID = 8446403367374890504L;

        private Integer sEcho = 1;
        private Integer iTotalRecords;
        private Integer iTotalDisplayRecords;
        private List<Object> aaData;

        public DataTableResponseInfo() {
        }

        public DataTableResponseInfo(Integer sEcho, Integer iTotalRecords, Integer iTotalDisplayRecords, List<Object> aaData) {
            this.sEcho = sEcho;
            this.iTotalRecords = iTotalRecords;
            this.iTotalDisplayRecords = iTotalDisplayRecords;
            this.aaData = aaData;
        }

        public Integer getsEcho() {
            return sEcho;
        }

        public Integer getiTotalRecords() {
            return iTotalRecords;
        }

        public Integer getiTotalDisplayRecords() {
            return iTotalDisplayRecords;
        }

        public List<Object> getAaData() {
            return aaData;
        }
    }

    public static class DataTableRequestInfo implements Serializable {

        private static final long serialVersionUID = 7675778509406471349L;

        private Integer echo;
        private Integer start;
        private Integer limit;
        private String[] columns;
        private String orderColumn;
        private String orderLaw;

        public DataTableRequestInfo() {
        }

        public DataTableRequestInfo(Integer echo, Integer start, Integer limit, String[] columns, String orderColumn, String orderLaw) {
            this.echo = echo;
            this.start = start;
            this.limit = limit;
            this.columns = columns;
            this.orderColumn = orderColumn;
            this.orderLaw = orderLaw;
        }

        @Override
        public String toString() {
            return "DataTableRequestInfo{" +
                    "echo=" + echo +
                    ", start=" + start +
                    ", limit=" + limit +
                    ", columns=" + Arrays.toString(columns) +
                    ", orderColumn='" + orderColumn + '\'' +
                    ", orderLaw='" + orderLaw + '\'' +
                    '}';
        }

        public Integer getEcho() {
            return echo;
        }

        public DataTableRequestInfo setEcho(Integer echo) {
            this.echo = echo;
            return this;
        }

        public Integer getStart() {
            return start;
        }

        public DataTableRequestInfo setStart(Integer start) {
            this.start = start;
            return this;
        }

        public Integer getLimit() {
            return limit;
        }

        public DataTableRequestInfo setLimit(Integer limit) {
            this.limit = limit;
            return this;
        }

        public String[] getColumns() {
            return columns;
        }

        public DataTableRequestInfo setColumns(String[] columns) {
            this.columns = columns;
            return this;
        }

        public String getOrderColumn() {
            return orderColumn;
        }

        public DataTableRequestInfo setOrderColumn(String orderColumn) {
            this.orderColumn = orderColumn;
            return this;
        }

        public String getOrderLaw() {
            return orderLaw;
        }

        public DataTableRequestInfo setOrderLaw(String orderLaw) {
            this.orderLaw = orderLaw;
            return this;
        }
    }

    public static String getBodyString(HttpServletRequest request) {
        int contentLength = request.getContentLength();
        if (contentLength <= 0) return null;

        InputStream in = null;
        InputStreamReader reader = null;
        BufferedReader bReader = null;
        try {
            request.setCharacterEncoding("UTF-8");
            in = request.getInputStream();
            if (in == null) throw new Exception("获取参数错误");

            reader = new InputStreamReader(in, StandardCharsets.UTF_8);
            bReader = new BufferedReader(reader);

            StringBuilder sb = new StringBuilder();
            String tmp;
            while ((tmp = bReader.readLine()) != null) {
                sb.append(tmp);
            }
            return sb.toString();
        } catch (Exception e) {
            return null;
        } finally {
            if (bReader != null) {
                try {
                    bReader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}
